﻿
Imports osi.root.formation
Imports osi.root.procedure
Imports osi.root.connector
Imports osi.root.template
Imports osi.root.utils
Imports osi.root.lock

Public Class delay_generate_device_pool(Of T)
    Inherits delay_generate_device_pool(Of T, _true)

    Public Sub New(ByVal max_count As UInt32,
                   ByVal identity As String,
                   Optional ByVal ctor As Func(Of pointer(Of T), event_comb) = Nothing,
                   Optional ByVal validator As Func(Of T, Boolean) = Nothing,
                   Optional ByVal closer As Action(Of T) = Nothing,
                   Optional ByVal device_id As Func(Of T, String) = Nothing)
        MyBase.New(max_count, identity, ctor, validator, closer, device_id)
    End Sub

    Public Sub New(ByVal max_count As UInt32,
                   Optional ByVal ctor As Func(Of pointer(Of T), event_comb) = Nothing,
                   Optional ByVal validator As Func(Of T, Boolean) = Nothing,
                   Optional ByVal closer As Action(Of T) = Nothing,
                   Optional ByVal device_id As Func(Of T, String) = Nothing)
        MyBase.New(max_count, ctor, validator, closer, device_id)
    End Sub

    Public Sub New(ByVal identity As String,
                   Optional ByVal ctor As Func(Of pointer(Of T), event_comb) = Nothing,
                   Optional ByVal validator As Func(Of T, Boolean) = Nothing,
                   Optional ByVal closer As Action(Of T) = Nothing,
                   Optional ByVal device_id As Func(Of T, String) = Nothing)
        MyBase.New(identity, ctor, validator, closer, device_id)
    End Sub

    Public Sub New(Optional ByVal ctor As Func(Of pointer(Of T), event_comb) = Nothing,
                   Optional ByVal validator As Func(Of T, Boolean) = Nothing,
                   Optional ByVal closer As Action(Of T) = Nothing,
                   Optional ByVal device_id As Func(Of T, String) = Nothing)
        MyBase.New(ctor, validator, closer, device_id)
    End Sub
End Class

Public Class delay_generate_device_pool(Of T, REUSABLE As _boolean)
    Inherits device_pool(Of T)
    Implements iasync_device_pool(Of T)

    Private Shared ReadOnly device_reusable As Boolean
    Private ReadOnly q As qless2(Of T)

    Shared Sub New()
        device_reusable = +(alloc(Of REUSABLE)())
    End Sub

    Public Sub New(ByVal max_count As UInt32,
                   ByVal identity As String,
                   Optional ByVal ctor As Func(Of pointer(Of T), event_comb) = Nothing,
                   Optional ByVal validator As Func(Of T, Boolean) = Nothing,
                   Optional ByVal closer As Action(Of T) = Nothing,
                   Optional ByVal device_id As Func(Of T, String) = Nothing)
        MyBase.New(max_count, identity, ctor, validator, closer, device_id)
        If device_reusable Then
            Me.q = New qless2(Of T)()
        End If
    End Sub

    Public Sub New(ByVal max_count As UInt32,
                   Optional ByVal ctor As Func(Of pointer(Of T), event_comb) = Nothing,
                   Optional ByVal validator As Func(Of T, Boolean) = Nothing,
                   Optional ByVal closer As Action(Of T) = Nothing,
                   Optional ByVal device_id As Func(Of T, String) = Nothing)
        MyBase.New(max_count, ctor, validator, closer, device_id)
        If device_reusable Then
            Me.q = New qless2(Of T)()
        End If
    End Sub

    Public Sub New(ByVal identity As String,
                   Optional ByVal ctor As Func(Of pointer(Of T), event_comb) = Nothing,
                   Optional ByVal validator As Func(Of T, Boolean) = Nothing,
                   Optional ByVal closer As Action(Of T) = Nothing,
                   Optional ByVal device_id As Func(Of T, String) = Nothing)
        MyBase.New(identity, ctor, validator, closer, device_id)
        If device_reusable Then
            Me.q = New qless2(Of T)()
        End If
    End Sub

    Public Sub New(Optional ByVal ctor As Func(Of pointer(Of T), event_comb) = Nothing,
                   Optional ByVal validator As Func(Of T, Boolean) = Nothing,
                   Optional ByVal closer As Action(Of T) = Nothing,
                   Optional ByVal device_id As Func(Of T, String) = Nothing)
        MyBase.New(ctor, validator, closer, device_id)
        If device_reusable Then
            Me.q = New qless2(Of T)()
        End If
    End Sub

    Protected NotOverridable Overrides Function get_device(ByVal r As pointer(Of T)) As event_comb
        Dim ec As event_comb = Nothing
        Return New event_comb(Function() As Boolean
                                  If device_reusable Then
                                      assert(Not q Is Nothing)
                                      Dim c As T = Nothing
                                      If q.pop(c) Then
                                          Return eva(r, c) AndAlso
                                                 goto_end()
                                      End If
                                  End If
                                  ec = create_new_device(r)
                                  Return waitfor(ec) AndAlso
                                         goto_next()
                              End Function,
                              Function() As Boolean
                                  Return ec.end_result() AndAlso
                                         goto_end()
                              End Function)
    End Function

    Protected NotOverridable Overrides Function release_device(ByVal c As T) As Boolean
        If device_reusable Then
            assert(Not q Is Nothing)
            q.push(c)
            Return True
        Else
            Return False
        End If
    End Function

    Protected NotOverridable Overrides Sub close_devices()
        If device_reusable Then
            close_existing_devices(q)
        End If
    End Sub

    Protected NotOverridable Overrides Function get_free_count() As UInt32
        If device_reusable Then
            assert(Not q Is Nothing)
            Return q.size()
        Else
            Return 0
        End If
    End Function

    Protected NotOverridable Overrides Function sync_get_device(ByRef r As T) As Boolean
        assert(False)
        Return False
    End Function

    Protected Overrides Sub Finalize()
        GC.KeepAlive(q)
        MyBase.Finalize()
    End Sub

    Public Shadows Function [get](ByVal o As pointer(Of T)) As event_comb Implements iasync_device_pool(Of T).get
        Return MyBase.get(o)
    End Function

    Public Shadows Function release(ByVal c As T) As Boolean Implements idevice_pool(Of T).release
        Return MyBase.release(c)
    End Function
End Class
